<template>
    <div id="role-main">
        <div class="roleList-herd">
            <div>
                <el-form :inline="true" :model="seachForm" class="demo-form-inline">
                    <el-form-item v-for="(item, index) in menuBtns" :key="index">
                        <el-button v-if="CREATE == item.icon || DELETE == item.icon" :type="item.icon"
                            @click="clickBtn(item.icon)">
                            {{
                                item.menuName }}</el-button>
                    </el-form-item>
                    <el-form-item>
                        <el-input v-model="paging.name" placeholder="角色名称"></el-input>
                    </el-form-item>
                    <el-form-item>
                        <el-button @click="onReSetSeach">重置</el-button>
                    </el-form-item>
                    <el-form-item>
                        <el-button type="primary" @click="init">查询</el-button>
                    </el-form-item>
                </el-form>
            </div>
        </div>

        <div class="role-body">
            <el-table ref="multipleTable" tooltip-effect="dark" @selection-change="handleSelectionChange"
                :data="pagingData.totalList" style="width: 100%">
                <el-table-column type="selection" width="55" :selectable="checkboxInit"> </el-table-column>
                <el-table-column prop="id" label="id" width="100" align="center"></el-table-column>
                <el-table-column prop="code" label="角色编码" width="180" align="center"></el-table-column>
                <el-table-column prop="name" label="用户名称" width="180" align="center"></el-table-column>
                <el-table-column prop="isDel" label="是否开启" width="180" align="center">
                    <template slot-scope="scope">
                        <el-tag v-if="!scope.row.isDel" type="success">开启</el-tag>
                        <el-tag v-else type="info">关闭</el-tag>
                    </template>
                </el-table-column>
                <el-table-column prop="roleType" label="角色类型" width="180" align="center">
                    <template slot-scope="scope">
                        <el-tag v-if="scope.row.roleType == '00'">系统</el-tag>
                        <el-tag v-if="scope.row.roleType == '01'" type="success">默认</el-tag>
                        <el-tag v-if="scope.row.roleType == '02'" type="info">普通</el-tag>
                    </template>
                </el-table-column>
                <el-table-column fixed="right" label="操作" min-width="120" align="center">
                    <template slot-scope="scope">
                        <!-- 默认用户和列表 -->
                        <div v-if="isSysDef(userInfo.userType) && !isSysDef(scope.row.roleType)">
                            <div class="btns" v-for="(item, index) in menuBtns" :key="index">
                                <el-button type="text" size="small" v-if="item.icon == UPDATE || item.icon == DELETE"
                                    @click="handleClick(item.perms, scope.row)" :style="getButtonStyle(item.icon)">{{
                                        item.menuName }}</el-button>
                            </div>
                        </div>
                        <!-- 不是默认用户 -->
                        <div v-if="!isSysDef(userInfo.userType) && scope.row.roleType == '02'">
                            <div class="btns" v-for="(item, index) in menuBtns" :key="index">
                                <el-button type="text" size="small" v-if="item.icon == UPDATE || item.icon == DELETE"
                                    @click="handleClick(item.perms, scope.row)" :style="getButtonStyle(item.icon)">{{
                                        item.menuName }}</el-button>
                            </div>
                        </div>
                    </template>
                </el-table-column>
            </el-table>
            <div v-if="pagingData && pagingData.totalList && pagingData.totalList.length > 0">
                <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
                    :current-page="pagingData.currentPage" :page-sizes="[10, 20, 30, 40]" :page-size="10"
                    layout="total, sizes, prev, pager, next, jumper" :total="pagingData.total">
                </el-pagination>
            </div>
        </div>

        <el-dialog title="添加角色" :visible.sync="dialogTableAddVisible">
            <el-form :model="addForm" ref="addForm">
                <el-form-item label="角色编码" prop="code" :label-width="formLabelWidth" :required="true">
                    <el-input v-model="addForm.code" autocomplete="off" placeholder="只能输入纯英文字母"></el-input>
                </el-form-item>
                <el-form-item label="角色名称" prop="name" :label-width="formLabelWidth" :required="true">
                    <el-input v-model="addForm.name" autocomplete="off"></el-input>
                </el-form-item>
                <!-- <el-form-item :label-width="formLabelWidth" v-if="isSysDef(userInfo.tenantType)">
                    <div class="sub-title">
                        · 默认角色类型 ： 其他租户下必须有一个默认角色类型 <br />
                        · 普通角色类型 ： 可以任意操作
                    </div>
                </el-form-item> -->
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="handleCancel">取 消</el-button>
                <el-button type="primary" @click="onSave">保存</el-button>
            </div>
        </el-dialog>

        <el-dialog title="编辑角色" :visible.sync="dialogTableEditVisible">
            <el-form :model="editForm" ref="editForm">
                <el-form-item label="角色编码" prop="code" :label-width="formLabelWidth" :required="true">
                    <el-input v-model="editForm.code" autocomplete="off" :disabled="true"></el-input>
                </el-form-item>
                <el-form-item label="角色名称" prop="name" :label-width="formLabelWidth" :required="true">
                    <el-input v-model="editForm.name" autocomplete="off"></el-input>
                </el-form-item>
                <el-form-item label="是否开启" :label-width="formLabelWidth">
                    <el-switch v-model="editForm.isDel" active-color="#13ce66" inactive-color="#ff4949" :active-value="0"
                        :inactive-value="1">
                    </el-switch>
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="handleCancel">取 消</el-button>
                <el-button type="primary" @click="onEdit">保存</el-button>
            </div>
        </el-dialog>

        <el-dialog title="分配路由菜单" :visible.sync="dialogTableBindVisible">
            <!-- <div style="margin-left:5%">解释：<b>M目录 C菜单 F按钮 Aapi</b></div> -->
            <el-form ref="form" :model="form" label-width="100px">
                <el-form-item label="角色名称">
                    <el-input v-model="form.name" :disabled="true" />
                </el-form-item>
                <el-form-item label="角色编码">
                    <el-input v-model="form.code" :disabled="true" />
                </el-form-item>
                <el-form-item label="菜单权限">
                    <el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">展开/折叠</el-checkbox>
                    <el-checkbox v-model="menuNodeAll"
                        @change="handleCheckedTreeNodeAll($event, 'menu')">全选/全不选</el-checkbox>
                    <el-checkbox v-model="menuCheckStrictly"
                        @change="handleCheckedTreeConnect($event, 'menu')">父子联动</el-checkbox>
                    <el-tree class="tree-border" :data="menuListData" show-checkbox ref="menu" node-key="id"
                        :check-strictly="!menuCheckStrictly" empty-text="暂无数据" :props="defaultProps"></el-tree>
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="handleCancel">取 消</el-button>
                <el-button type="primary" @click="onBindMenu">保存</el-button>
            </div>
        </el-dialog>

        <el-dialog title="分配API" :visible.sync="dialogTableBindVisibleApi">
            <el-form ref="form" :model="form" label-width="100px">
                <el-form-item label="角色名称">
                    <el-input v-model="form.name" :disabled="true" />
                </el-form-item>
                <el-form-item label="角色编码">
                    <el-input v-model="form.code" :disabled="true" />
                </el-form-item>
                <el-form-item label="菜单权限">
                    <el-checkbox v-model="apiExpand" @change="handleCheckedTreeExpand($event, 'api')">展开/折叠</el-checkbox>
                    <el-checkbox v-model="apiNodeAll" @change="handleCheckedTreeNodeAll($event, 'api')">全选/全不选</el-checkbox>
                    <el-checkbox v-model="apiCheckStrictly"
                        @change="handleCheckedTreeConnect($event, 'api')">父子联动</el-checkbox>
                    <el-tree class="tree-border" :data="apiListData" show-checkbox ref="api" node-key="id"
                        :check-strictly="!apiCheckStrictly" empty-text="暂无数据" :props="apidefaultProps"></el-tree>
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="handleCancel">取 消</el-button>
                <el-button type="primary" @click="onBindApi">保存</el-button>
            </div>
        </el-dialog>

    </div>
</template>

<script>
import { mapState } from 'vuex';
import { CREATE, UPDATE, DELETE, BIND, BIND_API, SYS_DEF } from "@/common/constant/Const";
import { getSecondStr, isSysDef } from "@/common/utils/strUtil";
import { menuBtnByParentId } from "@/common/utils/MenuBtnUtils";
import { roleListPaging, updateRole, createRole, deleteRole, bindMenu, bindResource, getMenu, getResource } from "@/common/api/role";
import { authTree } from "@/common/api/user";
import { resourcesListPaging } from "@/common/api/resources";
import { menuListPaging } from "@/common/api/menu";
export default {
    components: {
    },
    data() {
        return {
            CREATE,
            UPDATE,
            DELETE,
            BIND,
            BIND_API,
            menuBtns: [],
            seachForm: {},
            paging: {
                currentPage: 1,
                pageSize: 10,
            },
            pagingData: {},
            dialogTableAddVisible: false,
            addForm: {
            },
            formLabelWidth: "120px",
            dialogTableEditVisible: false,
            editForm: {},
            deleteForm: {
                ids: [],
            },
            dialogTableBindVisible: false,
            dialogTableBindVisibleApi: false,
            menuExpand: false,
            menuNodeAll: false,
            apiExpand: false,
            apiNodeAll: false,
            form: {

            },
            // 表单参数
            menuCheckStrictly: true,
            apiCheckStrictly: true,
            // 菜单列表
            menuListData: [],
            defaultProps: {
                children: 'children',
                label: 'menuName'
            },
            // api列表
            apiListData: [],
            apidefaultProps: {
                children: 'children',
                label: 'name'
            },
            userInfo: JSON.parse(sessionStorage.getItem("userInfo")),
        };
    },
    computed: {
        ...mapState({
            menuItem: state => state.tab.menuItem,
            // isSelectedTenant: state => state.tab.isSelectedTenant,
            // userInfo: state => state.tab.userInfo,
        }),
    },
    mounted() {
        this.getMenuBtn(this.menuItem.id);
        this.init();
        // 获取资源树
        resourcesListPaging({
            currentPage: 1,
            pageSize: 1000,
        }).then((res) => {
            if (res) {
                this.apiListData = res.data.totalList.filter((item => item.isDel != 1));
                this.apiListData = this.buildNestedStructure(this.apiListData)
            }
        })
        // 获取路由树
        authTree().then((res) => {
            if (res) {
                this.menuListData = res.data
            }
        })

    },
    methods: {
        getSecondStr,
        isSysDef,
        menuBtnByParentId,
        getMenuBtn(data) {
            menuBtnByParentId(data).then((respData) => {
                this.menuBtns = respData;
            }).catch((error) => {
                console.error("Error fetching menu buttons:", error);
            });
        },
        // 处理数据
        buildNestedStructure(data) {
            // 创建以 name 为键的对象
            const modelMap = {};
            data.forEach(item => {
                // 如果 modelName 不在 modelMap 中，初始化为对象结构
                if (!modelMap[item.modelName]) {
                    modelMap[item.modelName] = {
                        id: "1-" + item.modelId,
                        name: item.modelName,
                        children: []
                    };
                }

                // 添加到对应的 modelName 的 children 中
                modelMap[item.modelName].children.push({
                    id: item.id,
                    name: item.name,
                    children: []  // 默认空数组
                });
            });

            // 提取成数组返回
            return Object.values(modelMap);
        },
        // 查询数据
        init() {
            roleListPaging(this.paging).then((resp) => {
                this.pagingData = resp.data;
            });
        },
        // 重置
        onReSetSeach() {
            this.paging = {
                currentPage: 1,
                pageSize: 10,
            };
            this.init();
        },
        clickBtn(data) {
            if (CREATE == data) {
                this.dialogTableAddVisible = true;
            }
            if (UPDATE == data) {
            }
            if (DELETE == data) {
                this.$confirm('此操作将永久删除, 是否继续?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    this.onRemove();
                }).catch(() => {
                    this.deleteForm.ids = [];
                    this.$refs.multipleTable.clearSelection();
                    this.$message({
                        type: 'info',
                        message: '已取消删除'
                    });
                });
            }
        },
        // 分页回调
        handleSizeChange(val) {
            this.paging.pageSize = val;
            this.init();
        },
        // 分页回调
        handleCurrentChange(val) {
            this.paging.currentPage = val;
            this.init();
        },
        // 多选表时的回调
        handleSelectionChange(val) {
            this.deleteForm.ids = val.map(item => item.id);
        },
        // 是否可选择表格
        checkboxInit(row, index) {
            if (isSysDef(this.userInfo.userType)) {
                return !isSysDef(row.roleType);
            }
            return row.roleType == '02';
        },
        // 重置表单
        handleCancel() {
            this.dialogTableAddVisible = false;
            this.addForm = {
            };

            this.dialogTableEditVisible = false;
            this.editForm = {};
            this.deleteForm.ids = [];
            this.unBind = {};


            if (this.$refs.menu != undefined) {
                this.$refs.menu.setCheckedKeys([]);
            }
            if (this.$refs.api != undefined) {
                this.$refs.api.setCheckedKeys([]);
            }
            this.dialogTableBindVisible = false;
            this.dialogTableBindVisibleApi = false;
            this.menuExpand = false
            this.menuNodeAll = false
            this.apiExpand = false
            this.apiNodeAll = false
            this.menuCheckStrictly = true
            this.apiCheckStrictly = true
            this.form = {

            }

            // this.paging.tenantId = this.isSelectedTenant.id == '' ? null : this.isSelectedTenant.id;
        },
        // 新增按钮
        onSave() {
            // this.addForm.tenantId = this.isSelectedTenant.id
            createRole(this.addForm).then((resp) => {
                if (resp) {
                    this.init();
                    this.handleCancel();
                }
            });
        },
        // 删除
        onRemove() {
            deleteRole(this.deleteForm).then((resp) => {
                if (resp) {
                    this.init();
                    this.handleCancel();
                }
            })
        },
        // 检查是否需要应用红色字体
        getButtonStyle(perms) {
            if (this.DELETE == perms) {
                return { color: 'red' };
            }
            if (this.UNBIND == perms || this.UNBIND_API == perms) {
                return { color: '#E6A23C' };
            }
            // 默认样式（可以是空对象，或者你可以设置其他样式）
            return {};
        },
        // 确认修改
        onEdit() {
            updateRole(this.editForm).then((resp) => {
                if (resp) {
                    this.init();
                    this.handleCancel();
                }
            });
        },
        // 点击事件
        handleClick(type, data) {
            console.log(type, name);
            if ("EDIT" == type) {
                this.editForm = { ...data };
                this.dialogTableEditVisible = true;
            }
            if ("BIND_MENU" == type) {
                this.handleCancel();
                getMenu(data.id).then(res => {
                    this.form = { ...data };
                    this.dialogTableBindVisible = true;
                    let checkedKeys = res.data
                    this.$nextTick(() => {
                        this.handleCheckedTreeExpand(false, 'menu');
                    })
                    checkedKeys.forEach((v) => {
                        this.$nextTick(() => {
                            this.$refs.menu.setChecked(v, true, false);
                        });
                    });
                });
            }
            if ("BIND_RESOURCE" == type) {
                this.handleCancel();
                getResource(data.id).then(res => {
                    this.form = { ...data };
                    this.dialogTableBindVisibleApi = true;
                    let checkedKeys = res.data
                    this.$nextTick(() => {
                        this.handleCheckedTreeExpand(false, 'api');
                    })
                    checkedKeys.forEach((v) => {
                        this.$nextTick(() => {
                            this.$refs.api.setChecked(v, true, false);
                        });
                    });
                });
            }
            if ("DELETE" == type) {
                this.$confirm('此操作将永久删除, 是否继续?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    this.deleteForm.ids.push(data.id);
                    this.onRemove();
                }).catch(() => {
                    this.$message({
                        type: 'info',
                        message: '已取消删除'
                    });
                });
            }
        },
        // 分配路由
        onBindMenu() {
            bindMenu({
                menuIds: this.getMenuAllCheckedKeys(),
                roleId: this.form.id
            }).then((resp) => {
                if (resp) {
                    this.init();
                    this.handleCancel();
                }
            });
        },
        // 绑定角色菜单
        onBindApi() {
            // 去除resourceIds里的非数字字段
            let resourceIds = this.getApiAllCheckedKeys().filter((item) => {
                return !isNaN(item);
            });
            bindResource({
                resourceIds,
                roleId: this.form.id
            }).then((resp) => {
                if (resp) {
                    this.init();
                    this.handleCancel();
                }
            });
        },
        // 所有菜单节点数据
        getMenuAllCheckedKeys() {
            // 目前被选中的菜单节点
            let checkedKeys = this.$refs.menu.getCheckedKeys();
            // 半选中的菜单节点
            let halfCheckedKeys = this.$refs.menu.getHalfCheckedKeys();
            checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
            return checkedKeys;
        },
        // 所有部门节点数据
        getApiAllCheckedKeys() {
            // 目前被选中的部门节点
            let checkedKeys = this.$refs.api.getCheckedKeys();
            // 半选中的部门节点
            let halfCheckedKeys = this.$refs.api.getHalfCheckedKeys();
            checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
            return checkedKeys;
        },
        // 树权限（展开/折叠）
        handleCheckedTreeExpand(value, type) {
            console.log(value);
            if (type == 'menu') {
                let treeList = this.menuListData;
                this.setExpanded(treeList, value);
            } else if (type == 'api') {
                let treeList = this.apiListData;
                for (let i = 0; i < treeList.length; i++) {
                    this.$refs.api.store.nodesMap[treeList[i].id].expanded = value;
                }
            }
        },
        // 循环展开树节点
        setExpanded(treeList, value) {
            treeList.forEach(node => {
                // 设置当前节点的 expanded 属性
                this.$refs.menu.store.nodesMap[node.id].expanded = value;

                // 如果有子节点，递归调用设置子节点的 expanded 属性
                if (node.children && node.children.length > 0) {
                    this.setExpanded(node.children, value);
                }
            });
        },
        // 树权限（全选/全不选）
        handleCheckedTreeNodeAll(value, type) {
            if (type == 'menu') {
                this.$refs.menu.setCheckedNodes(value ? this.menuListData : []);
            } else if (type == 'api') {
                this.$refs.api.setCheckedNodes(value ? this.apiListData : []);
            }
        },
        // 树权限（父子联动）
        handleCheckedTreeConnect(value, type) {
            if (type == 'menu') {
                this.menuCheckStrictly = value ? true : false;
            } else if (type == 'api') {
                this.apiCheckStrictly = value ? true : false;
            }
        },
    },
};
</script>